import java.io.*;
import java.net.*;


public class UDPAdapter implements ISocket{
	private SyncUDPSocket _socket = null;
	private int _maxMessageLength;
	private int _timeout;
	private String _owner = null;
	private String _ownerIP = null;
	
	public UDPAdapter(String owner, String ownerIP, SyncUDPSocket socket, int maxMessageLength, int timeout) {
		_socket = socket;
		_maxMessageLength = maxMessageLength;
		_timeout = timeout;
		_owner = owner;
		_ownerIP = ownerIP;
	}
	
	public void initialize() throws IOException{
		_socket.setSoTimeout(_timeout);
	}
	
	//public InetAddress getInetAddress() {return _socket.getInetAddress();}

	public InetAddress getLocalAddress() {
		return _socket.getLocalAddress();
	}
	
	public int getLocalPort() {
		return _socket.getLocalPort();
	}
	
	@Override
	public Message receive() {
		byte[] buffer = new byte[_maxMessageLength];
		DatagramPacket packet = 
			new DatagramPacket(buffer,_maxMessageLength);
		
		try{_socket.receive(packet);}
		catch(IOException ex) {}
		
		int index = new String(buffer).indexOf('>');
		if (index == -1) {
			if (packet.getPort() > 0) {
				String sender = SessionsManager.getNameBySource(new Source(this, packet.getAddress(), packet.getPort()));
				if (sender == null)
					sender = "unknown";
				
				String strData = new String(buffer);
				String dataLog = String.format("wrong format in %s message\ncontent:%s\nfrom:%s\nip:%s\nudp:%s\nto:%s\nip:%s\nudp:%s",
						 Utils.GetPrefixMessage(strData), strData,
						 sender, Utils.InetToString(packet.getAddress()), packet.getPort(),
						 _owner, _ownerIP, _socket.getLocalPort());
				Proj350.logger.logError(dataLog);
			}		
			
			return null;
		}
		byte[] temp = new byte[index + 1];
		System.arraycopy(buffer, 0, temp, 0, index + 1);
		
		if (Validator.isValidMessage(new String(temp)))
			return new Message(temp, packet.getAddress(), packet.getPort());
		
		//Log error
		String sender = SessionsManager.getNameBySource(new Source(this, packet.getAddress(), packet.getPort()));
		if (sender == null)
			sender = "unknown";
		
		String strData = new String(buffer);
		String dataLog = String.format("wrong format in %s message\ncontent:%s\nfrom:%s\nip:%s\nudp:%s\nto:%s\nip:%s\nudp:%s",
				 Utils.GetPrefixMessage(strData), strData,
				 sender, Utils.InetToString(packet.getAddress()), packet.getPort(),
				 _owner, _ownerIP, _socket.getLocalPort());
		Proj350.logger.logError(dataLog);
		
		return null;
	}
	
	public void close(){_socket.close();}

	public boolean isAlive() {return _socket.isAlive();}
	
	@Override
	public void send(Message message) {
		DatagramPacket packet = 
			new DatagramPacket(message.getData(),message.getData().length,
					message.getAddress(), message.getPort());
		
		String destName = message.getDestPeerName();
		if (destName == null)
			destName = "unknown";
		
		String data = String.format("%s\nfrom:%s\nip:%s\nudp:%s\nto:%s\nip:%s\nudp:%s",
				new String(message.getData()),
				_owner, _ownerIP, _socket.getLocalPort(),
				destName, Utils.InetToString(message.getAddress()), message.getPort());
		
		Proj350.logger.logOutgoing(data);
		
		try {_socket.send(packet);}
		catch(IOException ex) { }
	}
	
	public String type() {
		return "UDP";
	}
}